package com.platform.modules.chat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObject;
import com.platform.common.config.PlatformConfig;
import com.platform.common.constant.AppConstants;
import com.platform.common.enums.YesOrNoEnum;
import com.platform.common.shiro.ShiroUtils;
import com.platform.common.upload.config.UploadConfig;
import com.platform.common.utils.redis.RedisUtils;
import com.platform.modules.chat.config.TencentConfig;
import com.platform.modules.chat.domain.ChatUser;
import com.platform.modules.chat.enums.ApplySourceEnum;
import com.platform.modules.chat.enums.FriendTypeEnum;
import com.platform.modules.chat.service.ChatTalkService;
import com.platform.modules.chat.service.ChatUserService;
import com.platform.modules.chat.service.ChatWeatherService;
import com.platform.modules.chat.utils.ParseContent;
import com.platform.modules.chat.vo.FriendVo06;
import com.platform.modules.chat.vo.FriendVo07;
import com.platform.modules.common.config.OssConfig;
import com.platform.modules.push.vo.PushParamVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统聊天 服务层实现
 * </p>
 */
@Service("chatTalkService")
public class ChatTalkServiceImpl implements ChatTalkService {

    @Autowired
    private TencentConfig tencentConfig;

    @Resource
    private ChatWeatherService weatherService;

    @Resource
    private ChatUserService chatUserService;

    @Autowired
    private OssConfig ossConfig;

    @Resource
    private RedisUtils redisUtils;

    /**
     * 好友列表
     */
    private static List<FriendVo06> friendList() {
        // 作文小助手
        Long turingId = 10001L;
        FriendTypeEnum turingType = FriendTypeEnum.TURING;
        FriendVo06 turing = new FriendVo06()
                .setUserId(turingId)
                .setChatNo(NumberUtil.toStr(turingId))
                .setNickName(turingType.getInfo())
                .setPortrait(AppConstants.DEFAULT_URL+"/help/10001.png")
                .setUserType(turingType);
        // 读图小助手
        /*Long weatherId = 10002L;
        FriendTypeEnum weatherType = FriendTypeEnum.WEATHER;
        FriendVo06 weather = new FriendVo06()
                .setUserId(weatherId)
                .setChatNo(NumberUtil.toStr(weatherId))
                .setNickName(weatherType.getInfo())
                .setPortrait(AppConstants.DEFAULT_URL+"/help/10002.png")
                .setUserType(weatherType);, weather*/
        // 答问小助手
        Long translationId = 10003L;
        FriendTypeEnum translationType = FriendTypeEnum.TRANSLATION;
        FriendVo06 translation = new FriendVo06()
                .setUserId(translationId)
                .setChatNo(NumberUtil.toStr(translationId))
                .setNickName(translationType.getInfo())
                .setPortrait(AppConstants.DEFAULT_URL+"/help/10003.png")
                .setUserType(translationType);
        return CollUtil.newArrayList(turing, translation);
    }

    @Override
    public List<FriendVo06> queryFriendList() {
        Long userId = ShiroUtils.getUserId();
        List<FriendVo06> userList = friendList();
        userList.add(BeanUtil.toBean(chatUserService.findById(userId), FriendVo06.class).setUserType(FriendTypeEnum.SELF));
        return userList;
    }

    @Override
    public FriendVo07 queryFriendInfo(Long userId) {
        Map<Long, FriendVo06> dataList = friendList().stream().collect(Collectors.toMap(FriendVo06::getUserId, a -> a, (k1, k2) -> k1));
        FriendVo06 friendVo = dataList.get(userId);
        if (friendVo == null) {
            return null;
        }
        return BeanUtil.toBean(friendVo, FriendVo07.class)
                .setIsFriend(YesOrNoEnum.YES)
                .setSource(ApplySourceEnum.SYS);
    }

    @Override
    public PushParamVo talk(Long userId, String content) {
        Map<Long, FriendVo06> dataList = friendList().stream().collect(Collectors.toMap(FriendVo06::getUserId, a -> a, (k1, k2) -> k1));
        FriendVo06 friendVo = dataList.get(userId);
        if (friendVo == null) {
            return null;
        }
        Long current = ShiroUtils.getUserId();
        PushParamVo paramVo = new PushParamVo()
                .setUserId(friendVo.getUserId())
                .setPortrait(friendVo.getPortrait())
                .setNickName(friendVo.getNickName())
                .setContent(content)
                .setUserType(friendVo.getUserType());
        ChatUser toUser = chatUserService.getById(current);
        Integer initnum = toUser.getInitnum();
        String fileUrl = "";
        if (initnum > 0) {
            switch (friendVo.getUserType()) {
                case TURING:
                    //content = TencentUtils.turing(tencentConfig, current, content);
                    if ("新一轮问题".equals(content)) {
                        content = "请提出下一轮问题";
                        redisUtils.delete(current + ":10001");
                        redisUtils.delete(current+"img");
                        redisUtils.delete(current+"replyimg");
                        String imgUrls = redisUtils.get(current+"imgurl");
                        if (null!=imgUrls&&!"".equals(imgUrls)) {
                            String[] fileUrlAry = imgUrls.split("#");
                            for (String imgUrl:fileUrlAry) {
                                String delFilePath = PlatformConfig.ROOT_PATH + imgUrl;
                                File imageFile = new File(delFilePath);
                                imageFile.delete();
                            }
                            redisUtils.delete(current+"imgurl");
                        }
                    }else {
                        String hasImg = redisUtils.get(current+"img");
                        if (null==hasImg||!"y".equals(hasImg)) {
                            content = "作文问题需要上传作文参考图";
                        }else {
                            com.alibaba.fastjson.JSONObject jsonObject = null;
                            try {
                                jsonObject = JSON.parseObject(content);
                            }catch (JSONException e) {}
                            if (null!=jsonObject&&"IMAGE".equals(jsonObject.getString("type"))) {
                                fileUrl = jsonObject.getString("url");
                                initnum = initnum-1;
                                ChatUser chatUser = new ChatUser()
                                        .setUserId(current)
                                        .setInitnum(initnum);
                                chatUserService.updateById(chatUser);
                                content = redisUtils.get(current+"replyimg");
                            }else {
                                initnum = initnum-1;
                                ChatUser chatUser = new ChatUser()
                                        .setUserId(current)
                                        .setInitnum(initnum);
                                chatUserService.updateById(chatUser);
                                String imgUrls = redisUtils.get(current+"imgurl");
                                String oldQuestion = redisUtils.get(current + ":10001");
                                content = ParseContent.OCR("has", PlatformConfig.ROOT_PATH, oldQuestion, imgUrls);
                            }
                        }
                    }
                    break;
                case WEATHER:
                    //content = weather(content);
                    com.alibaba.fastjson.JSONObject jsonObject = null;
                    try {
                        jsonObject = JSON.parseObject(content);
                    }catch (JSONException e) {}
                    if (null!=jsonObject&&"IMAGE".equals(jsonObject.getString("type"))) {
                        initnum = initnum - 1;
                        ChatUser chatUser1 = new ChatUser()
                                .setUserId(current)
                                .setInitnum(initnum);
                        chatUserService.updateById(chatUser1);
                        fileUrl = jsonObject.getString("url");
                        content = redisUtils.get(fileUrl);
                        String delFilePath = PlatformConfig.ROOT_PATH + fileUrl;
                        File imageFile = new File(delFilePath);
                        imageFile.delete();
                        redisUtils.delete(fileUrl);
                    }
                    break;
                case TRANSLATION:
                    //content = TencentUtils.translation(tencentConfig, content);
                    if ("新一轮问题".equals(content)) {
                        content = "请提出下一轮问题";
                        redisUtils.delete(current + ":10003");
                        redisUtils.delete(current + "reply");
                    }else {
                        content = redisUtils.get(current + "reply");
                        if (null!=content&&!"".equals(content)) {
                            initnum = initnum - 1;
                            ChatUser chatUser2 = new ChatUser()
                                    .setUserId(current)
                                    .setInitnum(initnum);
                            chatUserService.updateById(chatUser2);
                            redisUtils.delete(current + "reply");
                        }else {
                            content = "这个问题不好回答";
                        }
                    }
                    break;
            }
        }else {
            content = "您的提问次数已用完，请到我的->钱包充值完成充值！";
        }
        return paramVo.setContent(content).setFileUrl(fileUrl);
    }

    private String getFileBytes(String url) {
        UploadConfig uploadConfig = BeanUtil.toBean(ossConfig, UploadConfig.class);
        OSS ossClient = new OSSClientBuilder().build(uploadConfig.getRegion(), uploadConfig.getAccessKey(), uploadConfig.getSecretKey());
        OSSObject ossObject = ossClient.getObject(uploadConfig.getBucketName(), url);
        byte[] data = null;
        try {
            InputStream out = ossObject.getObjectContent();
            byte[] bytes = toByteArray(out);
            InputStream in = new ByteArrayInputStream(bytes);
            in = new FileInputStream(url);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            ossClient.shutdown();
        }
        //对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        //返回Base64编码过的字节数组字符串
        return encoder.encode(data);
    }
    public static byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[input.available()];
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
    }

    /**
     * 天气预报
     */
    private String weather(String content) {
        List<JSONObject> dataList = weatherService.queryByCityName(content);
        if (CollectionUtils.isEmpty(dataList)) {
            return "暂未找到结果";
        }
        StringBuilder builder = new StringBuilder();
        dataList.forEach(e -> {
            builder.append("城市：");
            builder.append(e.getStr("province"));
            builder.append(e.getStr("city"));
            builder.append("\n");
            builder.append("天气：");
            builder.append(e.getStr("weather"));
            builder.append("\n");
            builder.append("温度：");
            builder.append(e.getStr("temperature"));
            builder.append("℃");
            builder.append("\n");
            builder.append("风力：");
            builder.append(e.getStr("windpower"));
            builder.append("级");
            builder.append("\n");
            builder.append("湿度：");
            builder.append(e.getStr("temperature"));
            builder.append("RH");
            builder.append("\n");
            builder.append("\n");
        });
        return StrUtil.removeSuffix(builder.toString(), "\n\n");
    }
}
